
/* This header file contains the definition of the Message hierachy 

   The code contains a base class, a macro to create derived classes
   and the instantiations of the macro for all types of messages needed.

   To define a new type of message, the message creation macro has to be 
   called in the following manner:

   M4_CREATE_MESSAGE_TYPE(TypeName, listCopyCostructed, listSwapped)

   where the each of the lists looks like:

   </</ (att_name, att_type), .../>/>

   The attributes in the CopyConstructed list are copied in using assignment,
   the attributes in the swapped list are swaped in using the Swap() method.

   Hopefully only basic types are copied in, the rest are swapped in.

   The macro will create a class, called TypeName that has members
   called as the attributes specified that are directly accessible.
   A private constructor that insantiates all the attributes in the order
   specified is created.
   
   The method Type() is automatically created and will return the numeric type
   associated with the message. The static int TypeName::type is also defined
   as a public constant member that allows the numeric type to be retrieved.

   When a method is registered to receive messages of type TypeName, the numeric
   registration can be done using TypeName::type

   The function TypeNameFactory(EventProcessor*, arguments) is automatically 
   produced as well. It creates a message of type TypeName and sends it 
   to the specified EventProcessor. 

   To check that the message class is correctly generated, do:
   m4 -I m4_dir Message.h

   The output should look like a hand generated C++ code

   NOTE: all the copy constructed members are passed by value and all 
   the swapped members by reference (for efficiency).

	 WARNING: The messages needed to run tests should be placed into the file 
	 Messages-local.h.m4 in the test directory. This goes for the includes they
	 need as well. The file Messages-local.h.m4 is included at the end of 
	 this file. It is fine if it is missing
*/

#include "EventProcessor.h"
#include "MessageMacros.h"


////////////////////////////////////////////////
// INCLUDES OF DATATYPES USED BY THE MESSAGES

#ifndef _MESSAGE_H_
#define _MESSAGE_H_

dnl # The following lines should be uncommented if a debug class is used
dnl # the name of the class shold replace MessageDebug
dnl # define(DEBUG_CLASS, MessageDebug)

dnl # // M4 PREAMBLE CODE
include(MessagesFunctions.m4)
dnl # END OF M4 CODE

/**
   Base message class for all the messages that can be manipulated by
   the MultiMessageQueue class.

   Provides no functionality, just a basic type for messages. Allows only 
   determining the type as a integer constant to allow conversion to the
   real type.

   When functionality is added to deal with another type of message,
   this class should be inherited from. The derived type can have as
   much intrnal structure and as many methods as desired. They will
   be accessible when the conversion to the true type is performed
   using dynamic_cast.

   For each derived class the static member type and the function Type() 
   give the type as an int.
*/

class Message {
public:
  // constructor doing nothing
  Message() {}

  virtual ~Message() {}
	
  // Every new message type should redefine this
  virtual int Type(void) { return -1; }
	virtual const char* TypeName(void){ return "Message"; }
};



//////////// DIE MESSAGE /////////////
// THIS IS A SYSTEM WIDE MESSAGE, DO NOT ERASE

/**
   Message given to an EventProcessor when it's time to finish.
   The threads inside the EventProcessor are killed.
   Any EventProcessor automatically processes this type of message.

   Arguments: NONE

*/

M4_CREATE_MESSAGE_TYPE(DieMessage,<//>,<//>)

dnl The following functions needs to be left after the DieMessage definition

// Kill an EventProcessor and wait for it to die. 
// This is the preffered method (as oppposed to DieMessage_Factory) since 
// it ensures that the processor actually died.

inline 
void KillEvProc(EventProcessor& evProc){
			 DieMessage_Factory(evProc);
			 evProc.WaitForProcessorDeath();
}

dnl ==================================================================
dnl === ALL MESSAGES ADDED TO THIS FILE SHOULD BE ABOVE THIS LINE ====

m4_sinclude(Message-local.h.m4)
								
#endif //  _MESSAGE_H_
